package com.yuwubao.framework.swagger;

import com.google.common.base.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * <Description> <br>
 *
 * @author wk <br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2017/8/23 <br>
 * @see com.yuwubao <br>
 * @since V1.0<br>
 */
@Configuration
@EnableSwagger2
@Profile(value = {"dev","test"})
public class Swagger2Configuration {

    @Autowired
    private ApplicationContext applicationContext;

    @Value("${document.swagger2.groups}")
    private String[] groups;

    /**
     * 这个方法返回Runnable只是一个幌子，最重要的是执行方法里面的代码
     */
    @Bean
    public Runnable dynamicConfiguration() throws Exception {
        ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();

        if (null != groups && groups.length > 0) {
            Stream.of(groups).forEach(group -> {
                beanFactory.registerSingleton("-api-group-" + group, buildDocket(group, this.buildPaths(group)));
            });
        } else {
            beanFactory.registerSingleton("-api-group-default", buildDocket("", null));
        }

        return null;
    }


    private Docket buildDocket(String groupName, Predicate<String> paths) {

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(this.buildApiInfo())
                .globalOperationParameters(this.buildGlobalParameters());

        if (StringUtils.isNotEmpty(groupName)) {
            docket.groupName(groupName);
        }

        return docket.select()
                .apis(RequestHandlerSelectors.basePackage("com.yuwubao.uav.tool"))//要扫描的API(Controller)基础包
                .paths(null != paths ? paths : PathSelectors.any())
                .build();
    }


    private Predicate<String> buildPaths(String groupName) {
        return PathSelectors.regex("/" + groupName + ".*");
    }

    private ApiInfo buildApiInfo() {
        return new ApiInfoBuilder()
                .title("Restful API文档")
                .contact(new Contact("YuWuBao", "https://yuwubao.com/", ""))
                .version("1.0")
                .build();
    }

    private List<Parameter> buildGlobalParameters() {
        List<Parameter> globalParameters = new ArrayList<>();

        ParameterBuilder builder = new ParameterBuilder();

        builder.parameterType("header").modelRef(new ModelRef("string"));

        builder.name("accessToken").description("登录token").required(false).defaultValue("");

        globalParameters.add(builder.build());

        return globalParameters;
    }

}
